home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / ibm / ashc5.arc / EVAL.C < prev    next >
Text File  |  1990-07-15  |  7KB  |  232 lines

  1. /*
  2.  *      eval --- evaluate expression
  3.  *
  4.  *      an expression is constructed like this:
  5.  *
  6.  *      expr ::=  expr + term |
  7.  *                expr - term |
  8.  *                expr * term |
  9.  *                expr / term |
  10.  *                expr | term |
  11.  *                expr & term |
  12.  *                expr % term |
  13.  *                expr ^ term ;
  14.  *
  15.  *      term ::=  symbol |
  16.  *                * |         <-- program counter at start of current line
  17.  *                constant ;
  18.  *
  19.  *      symbol ::=  string of alphanumerics with initial alpha char,
  20.  *            underscore, or period ;
  21.  *
  22.  *      constant ::= hex constant |
  23.  *                   binary constant |
  24.  *                   octal constant |
  25.  *                   decimal constant |
  26.  *                   ascii constant ;
  27.  *
  28.  *      hex constant ::= $<hex digits> ;
  29.  *
  30.  *      octal constant ::= @<octal digits> ;
  31.  *
  32.  *      binary constant ::= %<binary digits> ;
  33.  *
  34.  *      decimal constant ::= <decimal digits> ;
  35.  *
  36.  *      ascii constant ::= '<any printing char> ;
  37.  *
  38.  */
  39. eval()
  40. {
  41.         int     left,right;     /* left and right terms for expression */
  42.         char    o;              /* operator character */
  43.  
  44. #ifdef DEBUG
  45.         printf("Evaluating %s\n",Optr);
  46. #endif
  47.         Force_byte = NO;
  48.     Force_word = NO;
  49.     Result = 0;
  50.         if(*Optr=='<'){
  51.                 Force_byte++;
  52.                 Optr++;
  53.                 }
  54.         else if(*Optr=='>'){
  55.                 Force_word++;
  56.                 Optr++;
  57.                 }
  58.     left = get_term();         /* pickup first part of expression */
  59.     if( Term_err ) return(NO);
  60.  
  61.     while( is_op(*Optr) ) {
  62.                 o = *Optr++; /* pickup connector and skip */
  63.         right = get_term();     /* pickup current rightmost side */
  64.         if( Term_err ) {
  65.             Result = 0;
  66.             return(NO);
  67.             }
  68.                 switch(o){
  69.                         case '+': left += right; break;
  70.                         case '-': left -= right; break;
  71.                         case '*': left *= right; break;
  72.                         case '/': left /= right; break;
  73.                         case '|': left |= right; break;
  74.                         case '&': left &= right; break;
  75.                         case '%': left %= right; break;
  76.                         case '^': left = left^right; break;
  77.                         }
  78.         }
  79.  
  80.     Result= left;
  81. #ifdef DEBUG
  82.         printf("Result=%x\n",Result);
  83.         printf("Force_byte=%d  Force_word=%d\n",Force_byte,Force_word);
  84. #endif
  85.     if( !any( *Optr, " \t\n,;" ) && *Optr!=EOS ) {
  86.         error( "Improper character in expression" );
  87.         return(NO);
  88.         }
  89.         return(YES);
  90. }
  91.  
  92. /*
  93.  *      is_op --- is character an expression operator?
  94.  */
  95. is_op(c)
  96. char c;
  97. {
  98.         if( any(c,"+-*/&%|^"))
  99.                 return(YES);
  100.         return(NO);
  101. }
  102.  
  103.  
  104. /*
  105.  *      get_term --- evaluate a single item in an expression
  106.  */
  107. get_term()
  108. {
  109.         char    hold[MAXBUF];
  110.         char    *tmp;
  111.         int     val = 0;        /* local value being built */
  112.         int     minus;          /* unary minus flag */
  113.         struct nlist *lookup(),*pointer;
  114.     struct link *pnt,*bpnt;
  115.  
  116.     Term_err = NO;
  117.  
  118.         if( *Optr == '-' ){
  119.                 Optr++;
  120.                 minus =YES;
  121.                 }
  122.         else
  123.                 minus = NO;
  124.  
  125.     while( *Optr == '#' ) Optr++;
  126.  
  127.     if( *Optr == '-' ) {    /* allow - on either side of # */
  128.        if( minus == NO ) {
  129.         Optr++;
  130.         minus = YES;
  131.         }
  132.        else {               /* don't allow - on both sides of # */
  133.         error("Minus signs on both sides of #");
  134.         Term_err = YES;
  135.         return(val);
  136.         }
  137.        }
  138.  
  139.         /* look at rest of expression */
  140.  
  141.         if(*Optr=='%'){ /* binary constant */
  142.                 Optr++;
  143.                 while( any(*Optr,"01"))
  144.                         val = (val * 2) + ( (*Optr++)-'0');
  145.                 }
  146.         else if(*Optr=='@'){ /* octal constant */
  147.                 Optr++;
  148.                 while( any(*Optr,"01234567"))
  149.                         val = (val * 8) + ((*Optr++)-'0');
  150.                 }
  151.         else if(*Optr=='$'){ /* hex constant */
  152.                 Optr++;
  153.         while( any(*Optr,"0123456789abcdefABCDEF")) {
  154.                         if( *Optr > '9' )
  155.                                 val = (val * 16) + 10 + (mapdn(*Optr++)-'a');
  156.                         else
  157.                 val = (val * 16) + ((*Optr++)-'0');
  158.             }
  159.                 }
  160.         else if( any(*Optr,"0123456789")){ /* decimal constant */
  161.                 while(*Optr >= '0' && *Optr <= '9')
  162.                         val = (val * 10) + ( (*Optr++)-'0');
  163.                 }
  164.         else if(*Optr=='*'){    /* current location counter */
  165.                 Optr++;
  166.                 val = Old_pc;
  167.                 }
  168.         else if(*Optr=='\''){   /* character literal */
  169.                 Optr++;
  170.         if(*Optr == EOS) {
  171.             error("NULL character constant not allowed");
  172.             val = 0;
  173.             Term_err = YES;
  174.             }
  175.         else {
  176.             val = *Optr++;
  177.             if(*Optr=='\'') Optr++; /* allow closing quote */
  178.             }
  179.                 }
  180.         else if( alpha(*Optr) ){ /* a symbol */
  181.                 tmp = hold;     /* collect symbol name */
  182.                 while(alphan(*Optr))
  183.                         *tmp++ = *Optr++;
  184.                 *tmp = EOS;
  185.                 pointer = lookup(hold);
  186.                   if (pointer != NULL)
  187.                    {
  188.                    if (Pass == 2)
  189.                     {
  190.                        pnt = pointer->L_list;
  191.                         bpnt = NULL;
  192.                         while (pnt != NULL)
  193.                          {
  194.                            bpnt = pnt;
  195.                            pnt = pnt->next;
  196.                          }
  197.                         pnt = (struct link *) alloc(sizeof(struct link));
  198.                       if (bpnt == NULL)
  199.                        pointer->L_list = pnt;
  200.                       else bpnt->next = pnt;
  201.                      pnt->L_num = Line_num;
  202.                     pnt->next = NULL;
  203.                     }
  204.                        val = Last_sym;
  205.                    }
  206.                 else{
  207.                         if(Pass==1){    /* forward ref here */
  208.                                 fwdmark();
  209.                                 if( !Force_byte )
  210.                                         Force_word++;
  211.                                 val = 0;
  212.                                 }
  213.                         }
  214.                 if(Pass==2 && Line_num==F_ref && Cfn==Ffn){
  215.                         if( !Force_byte  )
  216.                                 Force_word++;
  217.                         fwdnext();
  218.                         }
  219.                 }
  220.     else {  /* none of the above */
  221.         if( white(*Optr) ) error("Whitespace not allowed in expression");
  222.         else error("Missing or unidentifiable operand ");
  223.         val = 0;
  224.         Term_err = YES;
  225.         }
  226.  
  227.         if(minus)
  228.                 return(-val);
  229.         else
  230.                 return(val);
  231. }
  232.